/*
 * cimg_utilits.cpp
 *
 *  Created on: 2016年6月18日
 *      Author: guyadong
 */
#include "img_tool.h"
#include "CImgWrapper.h"
namespace gdface{
namespace img_tools{
/* image_matrix_param转为CImg
 * */
cimg_library::CImg<uint8_t> image_matrix_to_cimg(const image_matrix & src_img){
	cimg_library::CImg<uint8_t> cimg=cimg_library::CImg<uint8_t>(src_img.width,src_img.height,1,src_img.channels);
	uint8_t* ptr_r  = cimg._data;
    uint8_t* ptr_g = cimg._data + 1UL*cimg._width*cimg._height;
    uint8_t* ptr_b = cimg._data + 2UL*cimg._width*cimg._height;
	uint8_t* ptr_a = cimg._data + 3UL*cimg._width*cimg._height;
    uint32_t row_stride=get_row_stride(src_img);
    cimg_forY(cimg,y){
		const uint8_t* ptrs = src_img.pixels + y*row_stride*cimg._spectrum;
        switch (cimg._spectrum) {
    	case 1 : {
    		cimg_forX(cimg,x) *(ptr_r++) = *(ptrs++);
    	} break;
    	case 3 : {
    	  cimg_forX(cimg,x) {
    		*(ptr_r++) =*(ptrs++);
    		*(ptr_g++) = *(ptrs++);
    		*(ptr_b++) = *(ptrs++);
    	  }
    	} break;
    	case 4 : {
    	  cimg_forX(cimg,x) {
    		*(ptr_r++) = *(ptrs++);
    		*(ptr_g++) = *(ptrs++);
    		*(ptr_b++) = *(ptrs++);
    		*(ptr_a++) = *(ptrs++);
    	  }
    	} break;
        }
    }
	return cimg;
}
/*
 * 将检测到的目标以矩形框方式显示在图像上
 * norm为true时，objs_src提供的是归一化坐标
 * share为true时，在原图上画目标位置矩形，否则不修改原图
 **/
void display_face_rect(const cimg_library::CImg<uint8_t> & src_img
		,const object_info_vector& objs_src
		,bool norm
		,const std::string& title
		,bool shared=false
		){
	cimg_library::CImg<uint8_t> copy;
	cimg_library::CImg<uint8_t>& dst=shared?const_cast<cimg_library::CImg<uint8_t>&>(src_img):copy =src_img;
	auto objects=	norm?convert_def(objs_src,{int(src_img._width),int(src_img._height)}):objs_src;
	uint8_t color[] = { 255,0,0 };
	uint8_t text_color[] = { 0,255,0 };
	for(size_t i=0;i<objects.size();++i){
		auto face_info=objects[i].def;
		std::basic_stringstream<char> stream;
		stream << face_info.left << "," << face_info.top<<"\nW"<< face_info.width<<"H"<< face_info.height;
		dst.draw_text(int(face_info.left+1), int(face_info.top+1), stream.str().data(), text_color);
		dst.draw_rectangle(int(face_info.left),int(face_info.top),int(face_info.left+face_info.width),int(face_info.top+face_info.height),color,0.9f, ~0U);
	}
	dst.display(title.data());
}
/*
 * 将检测到的目标以矩形框方式显示在图像上
 * norm为true时，objs_src提供的是归一化坐标
 * share为true时，在原图上画目标位置矩形，否则不修改原图
 **/
void display_face_rect(const image_matrix & src_img
		,const object_info_vector& objs_src
		,bool norm
		,const std::string&title
		){
	cimg_library::CImg<uint8_t> img=image_matrix_to_cimg(src_img);
	display_face_rect(img,objs_src,norm,title,true);
}
void display(const image_matrix & src_img,const std::string& title){
	cimg_library::CImg<uint8_t> img=image_matrix_to_cimg(src_img);
	img.display(title.data());
}
image_matrix_v decode_image(SUPPORTED_FORMAT_TYPE format,const void*img_data,size_t size,bool gray){
	image_matrix_param src;
	switch(format){
	case GF_FMT_JPG:
		src=gray?load_jpeg_gray_mem((uint8_t*)img_data,size):load_jpeg_mem((uint8_t*)img_data,size);
		break;
	case GF_FMT_JP2:
		src=load_j2k_mem((uint8_t*)img_data,size,OPJ_CODEC_JP2);
		if(gray)src=to_gray_image_matrix(src);
		break;
	case GF_FMT_J2K:
		src=load_j2k_mem((uint8_t*)img_data,size,OPJ_CODEC_J2K);
		if(gray)src=to_gray_image_matrix(src);
		break;
	default:
		throw std::invalid_argument(ERROR_STR("unsupported image format"));
	}
	return reinterpret_cast<image_matrix_v&&>(src);
}

}/*img_tools*/
}/*namespace gdface*/


